package com.demo.project_template.base.pay.wxpay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.demo.project_template.base.pay.wxpay.service.WeChatNotifyService;
import com.demo.project_template.base.pay.wxpay.util.WxPayUtil;
import com.demo.project_template.base.pay.wxpay.vo.WxPayAsyncDecryptVO;
import com.demo.project_template.base.pay.wxpay.vo.WxPayAsyncReturnVo;
import com.demo.project_template.base.pay.wxpay.vo.WxPayAsyncVO;
import com.demo.project_template.base.pay.wxpay.wxenum.WxAsyncResponseEnum;
import com.demo.project_template.constant.OrderConstants;
import com.demo.project_template.entity.Order;
import com.demo.project_template.exception.ErrorCodeException;
import com.demo.project_template.exception.ErrorCodeExceptionEnum;
import com.demo.project_template.mapper.OrderMapper;
import com.demo.project_template.util.HttpUtil;
import com.demo.project_template.util.RedisUtil;
import lombok.extern.log4j.Log4j2;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.GeneralSecurityException;
import java.util.Date;


/**
 * 微信支付服务类（只实现V3接口）
 *
 * @author zhangkechen
 * @since 2022/9/13 17:32
 */
@Service
@Log4j2
@Transactional(rollbackFor = RuntimeException.class)
public class WeChatNotifyServiceImpl implements WeChatNotifyService {

    @Resource
    private WxPayUtil wxPayUtil;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 项目 订单支付回掉
     *
     * @param request
     * @return
     * @throws IOException
     * @throws GeneralSecurityException
     */
    @Override
    public WxPayAsyncReturnVo orderNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("微信项目 订单支付回掉回调开始");
        //处理通知参数
        WxPayAsyncDecryptVO wxPayAsyncDecryptRequestVo = getWxPayAsyncDecryptVO(request);
        /**
         * TODO 处理业务
         */
        //Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNo, wxPayAsyncDecryptRequestVo.getOutTradeNo()));
        //应答微信
        return new WxPayAsyncReturnVo(WxAsyncResponseEnum.WX_PAY_ASYNC_RESPONSE_SUCCESS);
    }

    /**
     * 用户充值订单回掉
     */
    @Override
    public WxPayAsyncReturnVo rechargeNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("微信项目 用户充值订单回掉开始");
        //处理通知参数
        WxPayAsyncDecryptVO wxPayAsyncDecryptRequestVo = getWxPayAsyncDecryptVO(request);
        /**
         *  TODO 处理业务
         * 校验金额
         * 修改订单状态
         * 添加余额
         * 根据订单号修改订单
         */
        //应答微信
        return new WxPayAsyncReturnVo(WxAsyncResponseEnum.WX_PAY_ASYNC_RESPONSE_SUCCESS);
    }

    @Nullable
    private WxPayAsyncDecryptVO getWxPayAsyncDecryptVO(HttpServletRequest request) {
        String body = HttpUtil.readData(request);
        WxPayAsyncVO wxPayAsyncVo = JSONObject.parseObject(body, WxPayAsyncVO.class);
        boolean b = wxPayUtil.verifySign(request, body);
        if (b) {
            log.info("通知验签成功");
        } else {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.SYSTEM_ERROR);
        }
        //解密
        String decryptedString = wxPayUtil.decryptToString(wxPayAsyncVo.getResource().getAssociated_data(), wxPayAsyncVo.getResource().getNonce(), wxPayAsyncVo.getResource().getCiphertext());
        log.info("微信支付回调 - 解密: {}", decryptedString);
        log.info("解密报文：{}", decryptedString);
        //序列化
        WxPayAsyncDecryptVO wxPayAsyncDecryptRequestVo = JSONObject.parseObject(decryptedString, WxPayAsyncDecryptVO.class);
        log.info("将解密报文反序列化：{}", wxPayAsyncDecryptRequestVo);
        return wxPayAsyncDecryptRequestVo;
    }

}
